import type { AdTableProps, AdColumn, AdFetchParams } from '../types/adTable';
import type { AdDetailFormProps } from '../types/adDetailForm';
import { ComponentFormSchema } from '@/components/Form';
import { TagEditor } from '@/components/Tag';
import { unref, computed, h } from 'vue';
import type { ComputedRef } from 'vue';
// import type { ComponentType } from '@/components/Form/src/types';
import { useI18n } from '@/hooks/web/useI18n';
import { isBoolean, isString, isArray, isFunction } from '@/utils/is';
import md5 from 'crypto-js/md5';
import { getInputNumberPrecision } from './index';
import { uploadApi } from '@/api/sys/upload';
import {
  isEmail,
  isIpv4Address,
  isIpv6Address,
  isUrl,
  isMobileNumber,
  isIdCard,
  isGuid,
} from '@/enums/regexEnum';

/**
 * 使用高级详情表单
 * @param propsRef 高级表格选项
 * @param reloadFn 重新加载方法
 * @returns 高级详情表单对象
 */
export function useAdDetailForm(
  propsRef: ComputedRef<AdTableProps>,
  reloadFn?: (opt?: AdFetchParams) => Promise<any>,
) {
  const { t } = useI18n();

  /** 获取详情窗体属性 */
  const getDetailFormProps = computed((): Partial<AdDetailFormProps> => {
    const { columns, detailForm } = unref(propsRef);
    const formSchemaColumns = renderAdDetailFormSchema(columns, detailForm);
    const formSchema = getFormSchema(formSchemaColumns);

    // 获取并处理表单标识
    let formIndex = detailForm?.formIndex;
    if (formIndex === '' || formIndex === null || formIndex === undefined) {
      const formSchemaObj: object[] = [];
      if (formSchema && formSchema.length > 0) {
        formSchema.forEach((item) => {
          formSchemaObj.push({ field: item.field, component: item.component });
        });
      }
      formIndex = md5(JSON.stringify(formSchemaObj)).toString();
      // console.log('formIndex', formIndex);
      // console.log('formIndex1', formSchemaObj);
      // console.log('formIndex2', JSON.stringify(formSchemaObj));
      // console.log('formIndex3', md5(JSON.stringify(formSchemaObj)));
    }

    let formHelpMessage = detailForm?.helpMessage;
    if (detailForm?.showFormSchemaInfo !== false) {
      const formSchemaInfo = `${t('common.form')}：${formIndex}`;
      if (!formHelpMessage) {
        formHelpMessage = formSchemaInfo;
      } else if (isString(formHelpMessage)) {
        formHelpMessage = [formHelpMessage, formSchemaInfo];
      } else if (isArray(formHelpMessage)) {
        formHelpMessage = [...formHelpMessage, formSchemaInfo];
      }
    }

    return {
      ...detailForm,
      /** 表单标识 */
      formIndex: formIndex,
      /** 固定 modal 的宽度 */
      width: detailForm?.width || '50%',
      /** 标题右侧提示文本 */
      helpMessage: formHelpMessage,
      /** 表单架构 */
      formSchema: detailForm?.formSchema || formSchema,
      /** 扩展 form 组件，增加 label 宽度，表单内所有组件适用，可以单独在某个项覆盖或者禁用 */
      labelWidth: detailForm?.labelWidth || 139,
      /** 重新加载表格数据方法 */
      reloadFn: detailForm?.reloadFn || reloadFn,
      /** 弹出框位置 */
      position: detailForm?.position || 'center',
      zIndex: detailForm?.zIndex || 800,
    };
  });

  //#region 渲染高级详情表单列表单架构
  /**
   * 渲染高级详情表单列表单架构
   * @param columns 列集合
   * @returns 处理后的高级列集合
   */
  function renderAdDetailFormSchema(
    columns: AdColumn[],
    detailForm?: AdDetailFormProps,
  ): AdColumn[] {
    const data: AdColumn[] = [];
    columns.forEach((item) => {
      const newItem = { ...item };
      //渲染表单架构
      const componentType = newItem.formSchema?.component || newItem.editComponent || undefined;
      newItem.formSchema = {
        field: newItem.dataIndex as string,
        label: newItem.title as string,
        component: componentType || 'Input',
        ...newItem.formSchema,
      };

      if (newItem.formVisible === false) {
        newItem.formSchema = {
          ...newItem.formSchema,
          ifShow: false,
          show: false,
        };
        // 加入至新集合
        data.push(newItem);
      } else {
        if (isBoolean(newItem.required) && !isFunction(newItem.formSchema.required)) {
          newItem.formSchema.required = newItem.formSchema.required || newItem.required;
        }
        if (isBoolean(newItem.formEditable) && !isFunction(newItem.formSchema.dynamicDisabled)) {
          newItem.formSchema.dynamicDisabled = !newItem.formEditable;
        }

        if (newItem.editComponentProps && !isFunction(newItem.formSchema.componentProps)) {
          newItem.formSchema.componentProps = {
            ...newItem.formSchema.componentProps,
            ...newItem.editComponentProps,
          };
        }

        //初始化编辑控件
        switch (newItem.dataType) {
          case 'enum':
            newItem.editComponent = newItem.editComponent || 'Select';
            newItem.formSchema.component = componentType || newItem.editComponent;
            if (
              newItem.formSchema.component === 'Select' &&
              newItem.enumData &&
              newItem.enumData.length > 0 &&
              !isFunction(newItem.formSchema.componentProps)
            ) {
              // @ts-ignore
              const showSearch = newItem.formSchema.componentProps?.showSearch;
              // @ts-ignore
              const optionFilterProp = newItem.formSchema.componentProps?.optionFilterProp;
              newItem.formSchema.componentProps = {
                ...newItem.formSchema.componentProps,
                options: [...newItem.enumData],
                showSearch: isBoolean(showSearch) ? showSearch : true,
                optionFilterProp: optionFilterProp || 'label',
              };
            }
            break;
          case 'integer':
          case 'number':
          case 'quantity':
          case 'price':
          case 'amount':
          case 'rate':
          case 'percentage':
          case 'measure':
            newItem.editComponent = newItem.editComponent || 'InputNumber';
            newItem.formSchema.component = componentType || newItem.editComponent;
            if (
              newItem.formSchema.component === 'InputNumber' &&
              !isFunction(newItem.formSchema.componentProps)
            ) {
              const numberPrecision = getInputNumberPrecision(newItem.dataType);
              newItem.formSchema.componentProps = {
                ...newItem.formSchema.componentProps,
                precision: numberPrecision >= 0 ? numberPrecision : undefined,
              };
            }
            break;
          case 'string':
          case 'email':
          case 'mobile':
          case 'url':
          case 'ipv4':
          case 'ipv6':
          case 'idcard':
          case 'guid':
            newItem.editComponent = newItem.editComponent || 'Input';
            newItem.formSchema.component = componentType || newItem.editComponent;
            if (newItem.formSchema.component === 'Input') {
              if (newItem.formSchema.rules === undefined || newItem.formSchema.rules === null) {
                newItem.formSchema.rules = [];
              }
              newItem.formSchema.rules.push({
                required: newItem.required,
                // @ts-ignore
                validator: async (rule, value) => {
                  if (value) {
                    let isFormatOk = true;
                    switch (newItem.dataType) {
                      case 'email':
                        isFormatOk = isEmail(value);
                        break;
                      case 'mobile':
                        isFormatOk = isMobileNumber(value);
                        break;
                      case 'url':
                        isFormatOk = isUrl(value);
                        break;
                      case 'ipv4':
                        isFormatOk = isIpv4Address(value);
                        break;
                      case 'ipv6':
                        isFormatOk = isIpv6Address(value);
                        break;
                      case 'idcard':
                        isFormatOk = isIdCard(value);
                        break;
                      case 'guid':
                        isFormatOk = isGuid(value);
                        break;
                    }
                    if (!isFormatOk) {
                      return Promise.reject(`${newItem.dataType}${t('common.formatErrorText')}`);
                    }
                    return Promise.resolve();
                  }
                  if (!value && newItem.required) {
                    return Promise.reject();
                  }
                  return Promise.resolve();
                },
                trigger: ['change', 'blur'],
              });
            }
            break;
          case 'text':
            // @ts-ignore
            newItem.editComponent = newItem.editComponent || 'InputTextArea';
            // @ts-ignore
            newItem.formSchema.component = componentType || newItem.editComponent;
            if (
              newItem.formSchema.component === 'InputTextArea' &&
              !isFunction(newItem.formSchema.componentProps)
            ) {
              // @ts-ignore
              const showCount = newItem.formSchema.componentProps?.showCount;
              newItem.formSchema.componentProps = {
                ...newItem.formSchema.componentProps,
                showSearch: isBoolean(showCount) ? showCount : true,
                // autosize: { minRows: 2, maxRows: 6 },
              };
            }
            break;
          case 'password':
            // @ts-ignore
            newItem.editComponent = newItem.editComponent || 'InputPassword';
            // @ts-ignore
            newItem.formSchema.component = componentType || newItem.editComponent;
            break;
          case 'boolean':
            newItem.editComponent = newItem.editComponent || 'Switch';
            newItem.formSchema.component = componentType || newItem.editComponent;
            if (
              newItem.formSchema.component === 'Switch' ||
              newItem.formSchema.component === 'Checkbox'
            ) {
              const defaultValue = newItem.formSchema.defaultValue;
              newItem.formSchema.defaultValue = isBoolean(defaultValue) ? defaultValue : false;
            }
            break;
          case 'datetime':
          case 'date':
            newItem.editComponent = newItem.editComponent || 'DatePicker';
            newItem.formSchema.component = componentType || newItem.editComponent;
            if (
              newItem.formSchema.component === 'DatePicker' &&
              !isFunction(newItem.formSchema.componentProps)
            ) {
              // @ts-ignore
              let showTime = newItem.formSchema.componentProps?.showTime;
              showTime = isBoolean(showTime) ? showTime : newItem.dataType === 'datetime';
              newItem.formSchema.componentProps = {
                ...newItem.formSchema.componentProps,
                showTime: showTime,
                valueFormat: showTime ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD',
              };
            }
            break;
          case 'time':
            newItem.editComponent = newItem.editComponent || 'TimePicker';
            newItem.formSchema.component = componentType || newItem.editComponent;
            break;
          case 'array':
            const formSchemaRender = ({ model, field }) => {
              return h(TagEditor, {
                value: model[field],
                editEnabled: newItem.formEditable,
                addTagText: t('common.addText'),
                onChange: (tags: string[]) => {
                  model[field] = tags;
                },
              });
            };
            newItem.formSchema = {
              ...newItem.formSchema,
              colProps: {
                ...newItem.formSchema?.colProps,
                // span: newItem.formSchema?.colProps?.span || 24,
                xs: newItem.formSchema?.colProps?.xs || 24, // <576px
                sm: newItem.formSchema?.colProps?.sm || 24, // ≥576px
                md: newItem.formSchema?.colProps?.md || 24, // ≥768px
                lg: newItem.formSchema?.colProps?.lg || 24, // ≥992px
                xl: newItem.formSchema?.colProps?.xl || 24, // ≥1200px
                xxl: newItem.formSchema?.colProps?.xxl || 24, // ≥1600px
                // xxxl: newItem.formSchema?.colProps?.xxxl || 24, // ≥2000px 3.0
              },
              render: newItem.formSchema?.render || formSchemaRender,
            };
            break;
          case 'image':
            newItem.formSchema.component =
              componentType || newItem.editComponent || 'ImageSelector';
            newItem.formSchema.componentProps = {
              accept: ['png', 'jpeg', 'jpg', 'bmp', 'ico', 'gif'],
              ...newItem.formSchema.componentProps,
            };
            break;
          case 'imageupload':
            newItem.formSchema.component = componentType || newItem.editComponent || 'ImageUpload';
            newItem.formSchema.componentProps = {
              accept: ['png', 'jpeg', 'jpg', 'bmp', 'ico', 'gif'],
              maxSize: 2, //M
              maxNumber: 1, //Infinity
              multiple: false,
              api: uploadApi,
              ...newItem.formSchema.componentProps,
            };
            break;
          case 'upload':
            newItem.formSchema.component = componentType || newItem.editComponent || 'Upload';
            newItem.formSchema.componentProps = {
              api: uploadApi,
              emptyHidePreview: true,
              accept: ['*'],
              maxSize: 10, //M
              maxNumber: Infinity, //Infinity
              multiple: false,
              ...newItem.formSchema.componentProps,
            };
            break;
        }

        // 根据控件类型设置布局
        switch (newItem.formSchema.component) {
          case 'Select':
          case 'ApiSelect':
          case 'ApiTreeSelect':
          case 'InputNumber':
          case 'Input':
          case 'InputPassword':
          case 'DatePicker':
          case 'TimePicker':
          case 'InputSearch':
          case 'InputCountDown':
          case 'TreeSelect':
          case 'MonthPicker':
          case 'RangePicker':
          case 'WeekPicker':
          case 'StrengthMeter':
          case 'IconPicker':
          case 'AutoComplete': // 自动完成
          case 'Cascader': // 级联选择
          case 'ApiCascader': // 级联选择
          case 'Rate': // 评分
          case 'Slider': // 滑动输入条
            if (!isFunction(newItem.formSchema.componentProps)) {
              switch (newItem.formSchema.component) {
                case 'Select':
                case 'ApiSelect':
                case 'ApiTreeSelect':
                  // @ts-ignore
                  const showSearch = newItem.formSchema.componentProps?.showSearch;
                  // @ts-ignore
                  const optionFilterProp = newItem.formSchema.componentProps?.optionFilterProp;
                  newItem.formSchema.componentProps = {
                    ...newItem.formSchema.componentProps,
                    showSearch: isBoolean(showSearch) ? showSearch : true,
                    optionFilterProp: optionFilterProp || newItem.dataIndex || 'lable',
                  };
                  break;
                case 'InputNumber':
                  let dataType:
                    | 'integer'
                    | 'number'
                    | 'quantity'
                    | 'price'
                    | 'amount'
                    | 'rate'
                    | 'percentage'
                    | 'measure' = 'number';
                  switch (newItem.dataType) {
                    case 'integer':
                    case 'number':
                    case 'quantity':
                    case 'price':
                    case 'amount':
                    case 'rate':
                    case 'percentage':
                    case 'measure':
                      dataType = newItem.dataType;
                      break;
                  }
                  const numberPrecision = getInputNumberPrecision(dataType);
                  newItem.formSchema.componentProps = {
                    ...newItem.formSchema.componentProps,
                    precision: numberPrecision >= 0 ? numberPrecision : undefined,
                  };
                  break;
              }
              newItem.formSchema.componentProps = {
                ...newItem.formSchema.componentProps,
                style: {
                  // @ts-ignore
                  ...newItem.formSchema.componentProps?.style,
                  // @ts-ignore
                  width: newItem.formSchema.componentProps?.style?.width || '100%',
                },
              };
            }

            newItem.formSchema.colProps = {
              ...newItem.formSchema.colProps,
              // span: newItem.formSchema?.colProps?.span || 12,
              xs: newItem.formSchema?.colProps?.xs || 24, // <576px
              sm: newItem.formSchema?.colProps?.sm || 24, // ≥576px
              md: newItem.formSchema?.colProps?.md || 24, // ≥768px
              lg: newItem.formSchema?.colProps?.lg || 24, // ≥992px
              xl: newItem.formSchema?.colProps?.xl || 12, // ≥1200px
              xxl: newItem.formSchema?.colProps?.xxl || 12, // ≥1600px
              // xxxl: newItem.formSchema?.colProps?.xxxl || 12, // ≥2000px 3.0
            };
            break;
          case 'InputTextArea':
          case 'InputGroup':
          case 'ApiTree':
          case 'ApiRadioGroup':
          case 'RadioButtonGroup':
          case 'RadioGroup':
          case 'CheckboxGroup':
            newItem.formSchema.componentProps = {
              ...newItem.formSchema.componentProps,
              style: {
                // @ts-ignore
                ...newItem.formSchema.componentProps?.style,
                // @ts-ignore
                width: newItem.formSchema.componentProps?.style?.width || '100%',
              },
            };
            newItem.formSchema.colProps = {
              ...newItem.formSchema.colProps,
              // span: newItem.formSchema?.colProps?.span || 12,
              xs: newItem.formSchema?.colProps?.xs || 24, // <576px
              sm: newItem.formSchema?.colProps?.sm || 24, // ≥576px
              md: newItem.formSchema?.colProps?.md || 24, // ≥768px
              lg: newItem.formSchema?.colProps?.lg || 24, // ≥992px
              xl: newItem.formSchema?.colProps?.xl || 24, // ≥1200px
              xxl: newItem.formSchema?.colProps?.xxl || 12, // ≥1600px
              // xxxl: newItem.formSchema?.colProps?.xxxl || 12, // ≥2000px 3.0
            };
            break;
          case 'Switch':
          case 'Checkbox':
            newItem.formSchema.colProps = {
              ...newItem.formSchema.colProps,
              // span: newItem.formSchema?.colProps?.span || 12,
              xs: newItem.formSchema?.colProps?.xs || 24, // <576px
              sm: newItem.formSchema?.colProps?.sm || 24, // ≥576px
              md: newItem.formSchema?.colProps?.md || 12, // ≥768px
              lg: newItem.formSchema?.colProps?.lg || 12, // ≥992px
              xl: newItem.formSchema?.colProps?.xl || 8, // ≥1200px
              xxl: newItem.formSchema?.colProps?.xxl || 6, // ≥1600px
              // xxxl: newItem.formSchema?.colProps?.xxxl || 12, // ≥2000px 3.0
            };
            break;
          case 'Render':
          case 'Divider':
            break;
          case 'ImageSelector':
            newItem.formSchema.colProps = {
              ...newItem.formSchema.colProps,
              // span: newItem.formSchema?.colProps?.span || 24,
              xs: newItem.formSchema?.colProps?.xs || 24, // <576px
              sm: newItem.formSchema?.colProps?.sm || 24, // ≥576px
              md: newItem.formSchema?.colProps?.md || 24, // ≥768px
              lg: newItem.formSchema?.colProps?.lg || 24, // ≥992px
              xl: newItem.formSchema?.colProps?.xl || 24, // ≥1200px
              xxl: newItem.formSchema?.colProps?.xxl || 24, // ≥1600px
              // xxxl: newItem.formSchema?.colProps?.xxxl || 24, // ≥2000px 3.0
            };
            break;
          case 'ImageUpload':
            newItem.formSchema.colProps = {
              ...newItem.formSchema.colProps,
              // span: newItem.formSchema?.colProps?.span || 24,
              xs: newItem.formSchema?.colProps?.xs || 24, // <576px
              sm: newItem.formSchema?.colProps?.sm || 24, // ≥576px
              md: newItem.formSchema?.colProps?.md || 24, // ≥768px
              lg: newItem.formSchema?.colProps?.lg || 24, // ≥992px
              xl: newItem.formSchema?.colProps?.xl || 24, // ≥1200px
              xxl: newItem.formSchema?.colProps?.xxl || 24, // ≥1600px
              // xxxl: newItem.formSchema?.colProps?.xxxl || 24, // ≥2000px 3.0
            };
            break;
          case 'Upload':
            newItem.formSchema.colProps = {
              ...newItem.formSchema.colProps,
              // span: newItem.formSchema?.colProps?.span || 12,
              xs: newItem.formSchema?.colProps?.xs || 24, // <576px
              sm: newItem.formSchema?.colProps?.sm || 24, // ≥576px
              md: newItem.formSchema?.colProps?.md || 24, // ≥768px
              lg: newItem.formSchema?.colProps?.lg || 24, // ≥992px
              xl: newItem.formSchema?.colProps?.xl || 12, // ≥1200px
              xxl: newItem.formSchema?.colProps?.xxl || 12, // ≥1600px
              // xxxl: newItem.formSchema?.colProps?.xxxl || 12, // ≥2000px 3.0
            };
            break;
        }

        // 将未设置的属性赋默认值
        if (!newItem.formSchema.field) {
          newItem.formSchema.field = newItem.dataIndex as string;
        }
        if (!newItem.formSchema.label) {
          newItem.formSchema.label = newItem.title as string;
        }
        if (detailForm?.showFormSchemaInfo !== false) {
          const formSchemaInfo = `${t('common.field')}：${newItem.dataIndex}`;
          if (!newItem.formSchema.helpMessage) {
            newItem.formSchema.helpMessage = formSchemaInfo;
          } else if (isString(newItem.formSchema.helpMessage)) {
            newItem.formSchema.helpMessage = [newItem.formSchema.helpMessage, formSchemaInfo];
          } else if (isArray(newItem.formSchema.helpMessage)) {
            newItem.formSchema.helpMessage = [...newItem.formSchema.helpMessage, formSchemaInfo];
          }
        }
        // 加入至新集合
        data.push(newItem);
      }
    });
    return data;
  }
  //#endregion

  /** 获取详情表单架构 */
  function getFormSchema(columns: AdColumn[]) {
    const formSchemaData: ComponentFormSchema[] = [];
    if (columns && columns.length > 0) {
      columns.forEach((item) => {
        if (item.formSchema) {
          formSchemaData.push(item.formSchema as ComponentFormSchema);
        }
      });
    }

    return formSchemaData;
  }

  return { getDetailFormProps };
}
